package cn.itcast.bos.web.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cn.itcast.bos.domain.base.Courier;
import cn.itcast.bos.domain.base.Standard;
import cn.itcast.bos.service.CourierService;
import cn.itcast.bos.web.action.common.BaseAction;

@ParentPackage("json-default")
@Namespace("/")
@Actions
@Controller
@Scope("prototype")
public class CourierAction extends BaseAction<Courier>{

	private static final long serialVersionUID = 1L;

	
	@Autowired
	private CourierService courierService;
	
	@Action(value="courier_save",results={@Result(name="success",type="redirect",location="./pages/base/courier.html")})
	public String save(){
		courierService.save(model);
		return SUCCESS;
	}
	
	@Action(value="courier_pageQuery",results={@Result(name="success",type="json")})
	public String pageQuery(){
		//无条件的查询
//		Pageable pageable = new PageRequest(page-1, rows);
//		Page<Courier> page = courierService.findPageQuery(pageable);
//		
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("total", page.getTotalElements());
//		map.put("rows", page.getContent());
//		ServletActionContext.getContext().getValueStack().push(map);
//		return SUCCESS;
		
		//有条件的查询
		Pageable pageable = new PageRequest(page-1, rows);
		//组织查询条件
		Specification<Courier> specification = new Specification<Courier>(){

			@Override
			public Predicate toPredicate(Root<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				/**
				 * 传递：
				 * 		Root<Courier> root：（连接语句的时候需要字段，获取字段的名称）代表Criteria查询的根对象，
				 * 							Criteria查询的查询根定义了实体类型，能为将来导航获得想要的结果，它与SQL查询中的FROM子句类似
				 * 		CriteriaQuery<?> query： （简单的查询可以使用CriteriaQuery）代表一个specific的顶层查询对象，
				 * 								 它包含着查询的各个部分，比如：select 、from、where、group by、order by等
				 * 		CriteriaBuilder cb：（复杂的查询可以使用CriteriaBuilder构建）用来构建CritiaQuery的构建器对象
				 * 返回：Predicate：封装查询条件
				 * 
				 */
				Predicate predicate = null;
				List<Predicate> list = new ArrayList<Predicate>();
				// 快递员工号
				if(StringUtils.isNotBlank(model.getCourierNum())){
					Predicate p = cb.equal(root.get("courierNum").as(String.class), model.getCourierNum());// 相当于条件：courierNum = gh001;
					list.add(p);
				}
				// 所属单位
				if(StringUtils.isNotBlank(model.getCompany())){
					Predicate p = cb.like(root.get("company").as(String.class), "%"+model.getCompany()+"%");// 相当于条件：company like %北京%;
					list.add(p);
				}
				// 快递员类型
				if(StringUtils.isNotBlank(model.getType())){
					Predicate p = cb.like(root.get("type").as(String.class), "%"+model.getType()+"%");// 相当于条件：type = %小件员%;
					list.add(p);
				}
				// 收派标准（多表）
				// 指定连接
				/*if(courier.getStandard()!=null && StringUtils.isNotBlank(courier.getStandard().getId().toString())){
					Join<Courier, Standard> join = root.join("standard",JoinType.INNER); // 相当于inner join t_courier c on t_standard s
					Predicate p = cb.equal(join.get("id").as(Integer.class), courier.getStandard().getId());// 相当于条件：s.id = 1;
					list.add(p);
				}*/
				if(model.getStandard()!=null && model.getStandard().getId()!=null){
					// 联合查询
					// 表示创建一个联合查询的对象
					Join<Courier, Standard> join = root.join("standard",JoinType.INNER);
					Predicate p = cb.equal(join.get("id").as(Integer.class), model.getStandard().getId());// standart.id = ?
					list.add(p);
				}
				// 构建条件的组合
				//表示存在查询条件
				if(list!=null && list.size()>0){
					Predicate[] p = new Predicate[list.size()]; // 构建一个数组，长度条件的长度
					predicate = cb.and(list.toArray(p));// 将查询条件从集合中的值转成数组中的值
				}

				return predicate;
			}
			
			
		};
		
		Page<Courier> page = courierService.findPageQueryCondition(specification, pageable);
		this.pushPageDataToValueStack(page);
		return SUCCESS;
		
	}
	
	//属性驱动
	private String ids;
	
	public void setIds(String ids) {
		this.ids = ids;
	}
	//批量作废
	@Action(value="courier_deleteCourier",results={@Result(name="success",type="redirect",location="./pages/base/courier.html")})
	public String deleteCourier(){
		String[] arrId = ids.split(",");
		courierService.deleteCourier(arrId);
		return SUCCESS;
	}
	//还原
	@Action(value="courier_huanyuanCourier",results={@Result(name="success",type="redirect",location="./pages/base/courier.html")})
	public String huanyuanCourier(){
		String[] arrId = ids.split(",");
		courierService.huanyuanCourier(arrId);
		return SUCCESS;
	}
}













